var array = ['a', ['b', 'c'], ['d', ['e', 'f']], [['g', ['h']], ['j']], ,'e', 123, null, undefined, function(){}, {name: 'AAAAA'}]
// console.log('flat ===>',array.flat())


// 递归
// function flat(arr) {
//   let arrResult = [];
//   arr.forEach(item => {
//     if (Array.isArray(item)) {
//       arrResult = arrResult.concat(flat(item));   // 递归
//       // 或者用扩展运算符
//       // arrResult.push(...arguments.callee(item));
//     } else {
//       arrResult.push(item);
//     }
//   });
//   return arrResult;
// }

// reduce

function flatByReduce(arr) {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatByReduce(cur) : cur)
  }, [])
}

console.log(a(array))
// stack

// function flatByStack(arr) {
//   let result = []
//   let stack = [...arr]
//   // console.log(stack)
//   while(stack.length !== 0) {
//     const item = stack.pop() // 取栈顶元素
//     // console.log('item', item)
//     if (Array.isArray(item)) { // 若为数组 展开一层 入栈
//       stack.push(...item)
//     } else {
//       if (item) {
//         result.unshift(item)
//       }
//     }
//   }
//   return result
// }

// flatByStack(array)

// prototype
// Array.prototype.flatRe = function(n = 1) {
//   if (!Number(n) || n < 0) {
//     return this
//   }
//   let arr = [].concat(this)
//   // while(n > 0) {
//   //   if (arr.some(x => Array.isArray(x))) { // 数组元素存在 数组的话，继续展开一层
//   //     arr = [].concat.apply([], arr)
//   //   } else {
//   //     break
//   //   }
//   //   n--
//   // }
//   // return arr
//   // 跳过空位
//   return n > 0 ? arr.reduce((pre, cur) => {
//     return pre.concat(Array.isArray(cur) ? cur.flatRe(--n) : cur)
//   }, []): arr.slice()
  
// }
// console.log(array.flatRe(2))